home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint110s.zoo
/
dosdir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-11
|
31KB
|
1,349 lines
/*
Copyright 1990,1991,1992 Eric R. Smith.
Copyright 1992,1993,1994 Atari Corporation.
All rights reserved.
*/
/* DOS directory functions */
#include "mint.h"
extern int aliasdrv[]; /* in filesys.c */
/* change to a new drive: should always return a map of valid drives */
long ARGS_ON_STACK
d_setdrv(d)
int d;
{
long r;
extern long dosdrvs; /* in filesys.c */
r = drvmap() | dosdrvs | PSEUDODRVS;
TRACE(("Dsetdrv(%d)", d));
if (d < 0 || d >= NUM_DRIVES || (r & (1L << d)) == 0) {
DEBUG(("Dsetdrv: invalid drive %d", d));
return r;
}
curproc->base->p_defdrv = curproc->curdrv = d;
return r;
}
long ARGS_ON_STACK
d_getdrv()
{
TRACE(("Dgetdrv"));
return curproc->curdrv;
}
long ARGS_ON_STACK
d_free(buf, d)
long *buf;
int d;
{
fcookie *dir = 0;
FILESYS *fs;
fcookie root;
long r;
TRACE(("Dfree(%d)", d));
/* drive 0 means current drive, otherwise it's d-1 */
if (d)
d = d-1;
else
d = curproc->curdrv;
/* If it's not a standard drive or an alias of one, get the pointer to
the filesystem structure and use the root directory of the
drive. */
if (d < 0 || d >= NUM_DRIVES) {
int i;
for (i = 0; i < NUM_DRIVES; i++) {
if (aliasdrv[i] == d) {
d = i;
goto aliased;
}
}
fs = get_filesys (d);
if (!fs)
return EDRIVE;
r = fs->root (d, &root);
if (r < 0)
return r;
r = (*fs->dfree) (&root, buf);
release_cookie (&root);
return r;
}
/* check for a media change -- we don't care much either way, but it
* does keep the results more accurate
*/
(void)disk_changed(d);
aliased:
/* use current directory, not root, since it's more likely that
* programs are interested in the latter (this makes U: work much
* better)
*/
dir = &curproc->curdir[d];
if (!dir->fs) {
DEBUG(("Dfree: bad drive"));
return EDRIVE;
}
return (*dir->fs->dfree)(dir, buf);
}
long ARGS_ON_STACK
d_create(path)
const char *path;
{
fcookie dir;
long r;
char temp1[PATH_MAX];
TRACE(("Dcreate(%s)", path));
r = path2cookie(path, temp1, &dir);
if (r) {
DEBUG(("Dcreate(%s): returning %ld", path, r));
return r; /* an error occured */
}
/* check for write permission on the directory */
r = dir_access(&dir, S_IWOTH);
if (r) {
DEBUG(("Dcreate(%s): write access to directory denied",path));
release_cookie(&dir);
return r;
}
r = (*dir.fs->mkdir)(&dir, temp1, DEFAULT_DIRMODE & ~curproc->umask);
release_cookie(&dir);
return r;
}
long ARGS_ON_STACK
d_delete(path)
const char *path;
{
fcookie parentdir, targdir;
long r;
PROC *p;
int i;
XATTR xattr;
char temp1[PATH_MAX];
TRACE(("Ddelete(%s)", path));
r = path2cookie(path, temp1, &parentdir);
if (r) {
DEBUG(("Ddelete(%s): error %lx", path, r));
release_cookie(&parentdir);
return r;
}
/* check for write permission on the directory which the target
* is located
*/
if ((r = dir_access(&parentdir, S_IWOTH)) != 0) {
DEBUG(("Ddelete(%s): access to directory denied", path));
release_cookie(&parentdir);
return r;
}
/* now get the info on the file itself */
r = relpath2cookie(&parentdir, temp1, NULL, &targdir, 0);
if (r) {
bailout:
release_cookie(&parentdir);
DEBUG(("Ddelete: error %ld on %s", r, path));
return r;
}
if ((r = (*targdir.fs->getxattr)(&targdir, &xattr)) != 0) {
release_cookie(&targdir);
goto bailout;
}
/* if the "directory" is a symbolic link, really unlink it */
if ( (xattr.mode & S_IFMT) == S_IFLNK ) {
r = (*parentdir.fs->remove)(&parentdir, temp1);
} else if ( (xattr.mode & S_IFMT) != S_IFDIR ) {
DEBUG(("Ddelete: %s is not a directory", path));
r = EPTHNF;
} else {
/* don't delete anyone else's root or current directory */
for (p = proclist; p; p = p->gl_next) {
if (p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q)
continue;
for (i = 0; i < NUM_DRIVES; i++) {
if (samefile(&targdir, &p->root[i])) {
DEBUG(("Ddelete: directory %s is a root directory",
path));
noaccess:
release_cookie(&targdir);
release_cookie(&parentdir);
return EACCDN;
} else if (samefile(&targdir, &p->curdir[i])) {
if (i == p->curdrv && p != curproc) {
DEBUG(("Ddelete: directory %s is in use",
path));
goto noaccess;
} else {
release_cookie(&p->curdir[i]);
dup_cookie(&p->curdir[i], &p->root[i]);
}
}
}
}
release_cookie(&targdir);
r = (*parentdir.fs->rmdir)(&parentdir, temp1);
}
release_cookie(&parentdir);
return r;
}
long ARGS_ON_STACK
d_setpath(path)
const char *path;
{
fcookie dir;
int drv = curproc->curdrv;
int i;
char c;
long r;
XATTR xattr;
TRACE(("Dsetpath(%s)", path));
r = path2cookie(path, follow_links, &dir);
if (r) {
DEBUG(("Dsetpath(%s): returning %ld", path, r));
return r;
}
if (path[0] && path[1] == ':') {
c = *path;
if (c >= 'a' && c <= 'z')
drv = c-'a';
else if (c >= 'A' && c <= 'Z')
drv = c-'A';
}
r = (*dir.fs->getxattr)(&dir, &xattr);
if (r < 0) {
DEBUG(("Dsetpath: file '%s': attributes not found", path));
release_cookie(&dir);
return r;
}
if (!(xattr.attr & FA_DIR)) {
DEBUG(("Dsetpath(%s): not a directory",path));
release_cookie(&dir);
return EPTHNF;
}
if (denyaccess(&xattr, S_IROTH|S_IXOTH)) {
DEBUG(("Dsetpath(%s): access denied", path));
release_cookie(&dir);
return EACCDN;
}
/*
* watch out for symbolic links; if c:\foo is a link to d:\bar, then
* "cd c:\foo" should also change the drive to d:
*/
if (drv != UNIDRV && dir.dev != curproc->root[drv].dev) {
for (i = 0; i < NUM_DRIVES; i++) {
if (curproc->root[i].dev == dir.dev &&
curproc->root[i].fs == dir.fs) {
if (drv == curproc->curdrv)
curproc->curdrv = i;
drv = i;
break;
}
}
}
release_cookie(&curproc->curdir[drv]);
curproc->curdir[drv] = dir;
return 0;
}
/* jr: like d_getpath, except that the caller provides a limit
for the max. number of characters to be put into the buffer.
Inspired by POSIX.1, getcwd(), 5.2.2 */
long ARGS_ON_STACK
d_getcwd(path, drv, size)
char *path;
int drv, size;
{
fcookie *dir, *root;
long r;
char buf[PATH_MAX];
FILESYS *fs;
TRACE(("Dgetcwd(%c, %d)", drv + '@', size));
if (drv < 0 || drv > NUM_DRIVES)
return EDRIVE;
drv = (drv == 0) ? curproc->curdrv : drv-1;
root = &curproc->root[drv];
if (!root->fs) { /* maybe not initialized yet? */
changedrv(drv);
root = &curproc->curdir[drv];
if (!root->fs)
return EDRIVE;
}
fs = root->fs;
dir = &curproc->curdir[drv];
if (!(fs->fsflags & FS_LONGPATH)) {
r = (*fs->getname)(root, dir, buf, PATH_MAX);
if (r) return r;
if (strlen(buf) < size) {
strcpy(path, buf);
return 0;
} else {
return ERANGE;
}
}
return (*fs->getname)(root, dir, path, size);
}
long ARGS_ON_STACK
d_getpath(path, drv)
char *path;
int drv;
{
TRACE(("Dgetpath(%c)", drv + '@'));
return d_getcwd(path, drv, PATH_MAX);
}
long ARGS_ON_STACK
f_setdta(dta)
DTABUF *dta;
{
TRACE(("Fsetdta: %lx", dta));
curproc->dta = dta;
curproc->base->p_dta = (char *)dta;
return 0;
}
long ARGS_ON_STACK
f_getdta()
{
long r;
r = (long)curproc->dta;
TRACE(("Fgetdta: returning %lx", r));
return r;
}
/*
* Fsfirst/next are actually implemented in terms of opendir/readdir/closedir.
*/
long ARGS_ON_STACK
f_sfirst(path, attrib)
const char *path;
int attrib;
{
char *s, *slash;
FILESYS *fs;
fcookie dir, newdir;
DTABUF *dta;
DIR *dirh;
XATTR xattr;
long r;
int i, havelabel;
char temp1[PATH_MAX];
TRACE(("Fsfirst(%s, %x)", path, attrib));
r = path2cookie(path, temp1, &dir);
if (r) {
DEBUG(("Fsfirst(%s): path2cookie returned %ld", path, r));
return r;
}
/*
* we need to split the last name (which may be a pattern) off from
* the rest of the path, even if FS_KNOPARSE is true
*/
slash = 0;
s = temp1;
while (*s) {
if (*s == '\\')
slash = s;
s++;
}
if (slash) {